﻿using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace DataCollectionSystem_attach.Subpage
{
    public class TcpClientWrapper
    {
        private readonly string _serverAddress;   //IP地址

        private readonly int _port;               //端口号

        private TcpClient _client;                //套接字

        private NetworkStream _stream;            //网络字节流

        private Thread _receiveThread;            //线程

        public bool _isConnected = false;                //判断网络连接

        public bool _isRunning;                  //判断线程是否在运行

        private string Heartbeat_Data = "OK";      //发送心跳的内容

        public delegate void MessageReceivedHandler(string message);

        public event MessageReceivedHandler MessageReceived;         //接收信息委托

        public delegate void CommunicationStatus_NO();

        public event CommunicationStatus_NO CStatus_NO;         //通讯状态

        public delegate void CommunicationStatus_OK();

        public event CommunicationStatus_OK CStatus_OK;         //接收信息委托

        public TcpClientWrapper(string serverAddress, int port)
        {
            _serverAddress = serverAddress;
            _port = port;
        }

        //连接函数
        public void Connect()
        {
            _client = new TcpClient();
            try
            {
                _client.Connect(_serverAddress, _port);

                _stream = _client.GetStream();
                _isConnected = true;
                _isRunning = true;

                //启动心跳检测线程
                var heartbeatThread = new Thread(SendHeartbeat);

                heartbeatThread.IsBackground = true;
                heartbeatThread.Start();
            }
            catch (Exception)
            {
                Thread.Sleep(1000);
                Reconnect1();

                //Console.WriteLine("aaa");
            }

            _receiveThread = new Thread(ReceiveMessage);
            _receiveThread.IsBackground = true;
            _receiveThread.Start();
        }

        //断开连接释放资源
        public void Disconnect()
        {
            _isConnected = false;
            _isRunning = false;
            try
            {
                if (_client != null)
                {
                    _client.Close();
                }
            }
            catch (Exception)
            {
            }
        }

        //发送消息
        public void SendMessage(byte[] message)
        {
            if (!_isConnected) return;
            try
            {
                _stream.Write(message, 0, message.Length);
            }
            catch
            {
                _isConnected = false;

                //Console.WriteLine($"发送消息失败：{e.Message}");
            }
        }

        //读取消息
        private void ReceiveMessage()
        {
            while (_isRunning)
            {
                try
                {
                    if (_client.Available > 0)
                    {
                        var buffer = new byte[512];
                        _stream.Read(buffer, 0, 8);
                        string str = BitConverter.ToString(buffer);
                        str = BitConverter.ToString(buffer).Replace("-", "").Substring(0, 8);
                        uint num = uint.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier);
                        MessageReceived?.Invoke(num.ToString()); //委托消息
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine($"接收消息失败：{e.Message}");
                    Reconnect();
                }
            }
        }

        //发送心跳消息
        private void SendHeartbeat()
        {
            while (_isRunning)
            {
                Thread.Sleep(50);
                try
                {
                    //SendMessage(Encoding.UTF8.GetBytes("Heartbeat"));
                    _stream.Write(Encoding.UTF8.GetBytes(Heartbeat_Data), 0, Heartbeat_Data.Length);

                    CStatus_OK?.Invoke();
                }
                catch
                {
                    //Console.WriteLine($"发送心跳失败：{e.Message}");
                    CStatus_NO?.Invoke();
                    Reconnect();
                    break;
                }

                Thread.Sleep(5950); //10秒钟发送一次心跳包
            }
        }

        //重连函数
        public void Reconnect()
        {
            Disconnect();
            while (!_isConnected)
            {
                try
                {
                    Connect();
                }
                catch
                {
                    //Console.WriteLine($"重连失败：{e.Message}");
                }

                Thread.Sleep(3000); //3秒钟尝试重新连接一次
            }
        }

        //重连函数
        public void Reconnect1()
        {
            Disconnect();
            try
            {
                Connect();
            }
            catch
            {
                //Console.WriteLine($"重连失败：{e.Message}");
            }
        }
    }
}